package com.zytech.zspider.task.impl;

import com.zytech.modules.lang.Function;
import com.zytech.modules.lang.Langs;
import com.zytech.modules.lang.Requires;
import com.zytech.zspider.core.TaskDefinition;
import com.zytech.zspider.core.TaskGenDefinition;
import com.zytech.zspider.logger.Loggers;
import com.zytech.zspider.task.*;

import java.util.List;

/**
 * @author siuming
 */
public class TaskGeneratorImpl implements TaskGenerator {
    private final TaskExpressionEvaluator expressionEvaluator;

    /**
     * @param expressionEvaluator
     */
    public TaskGeneratorImpl(TaskExpressionEvaluator expressionEvaluator) {
        Requires.notNull(expressionEvaluator, "expressionEvaluator must not be null.");
        this.expressionEvaluator = expressionEvaluator;
    }

    @Override
    public List<TaskDefinition> generateTasks(TaskContext context, TaskGenDefinition def) {
        Requires.notNull(context, "context must not be null.");
        Requires.notNull(def, "def must not be null.");

        Loggers.me().info(getClass(), "Generating Tasks using {}.", def);
        final TaskGenDefinition usingDef = def;
        List<TaskDefinition> subtasks = (List<TaskDefinition>) expressionEvaluator.eval(usingDef.getGenerateExpr(), context);

        return Langs.map(subtasks, new Function<TaskDefinition, TaskDefinition>() {
            @Override
            public TaskDefinition apply(TaskDefinition taskDefinition) {
                return taskDefinition.onStart(usingDef.getStartExpr())
                        .onFinish(usingDef.getFinishExpr())
                        .collects(usingDef.getCollectExprs())
                        .onResult(usingDef.getPipelineSettings())
                        .subtaskGenDefinitions(usingDef.getNexts());
            }
        });
    }
}
